//future的其他成员函数：
//
// 枚举值future_status状态：
// std::future_status status = result.wait_for(std::chrono::seconds(1));
// 在其下面有3个枚举值
// 分别是timeout：超时
//		ready：已做好准备
//		deferred：延迟
//
// future的成员函数
// 成员函数：wait_for（charono）
// 返回一个future-status枚举变量
// 等待一个一段时间，阻塞主线程
// 
// 
// share-future类模板
// future类模板中，get（）方法只能被调用一次，这导致了一些问题，如果我们希望
// 多个线程中使用get（）得到线程的结果，实现起来比较麻烦
// 所以为了解决这个问题，引入了share-future类模板
// 
// share-future的get（）函数是把数据赋值给相应的变量
// 可以直接接受get-future的返回值
// 也可以利用future的share（）方法把future对象转换为share-future对象
// 利用move直接把future对象交给share-future对象
// share_future<int > future_s=(request.share());
// share（）也是移动语义，之后原future对象空了
//也可以直接把get-future的返回值接受到share-future
//share_future<int > future_s=(mypt.get_future());
// 
// future对象的成员函数
// bool valid（）；判断future对象是否可以使用get（），即是否为空
// 如果不为空则返回true
// 
//原子操作概念：
//互斥量用来在多线程编程中保护共享数据。
//
//试想：
//初始化 int i=5；
//线程a 读取	int b=i；
//线程b	写入	i=10；
//此时可能出现的情况是线程a取到的值可能是5，也可能是10
//但是实际上不是这样，在数据切换时，我们可能收到意想不到的值，
//可能既不是5也不是10
//原因：即使一个简单的复制语句，在底层也会多步进行
//我们可以利用互斥量来解决这个问题
//加锁互斥量会大幅降低程序的效率，（加锁解锁了200000次）
//
//此时我们可以利用原子操作，他相当于一种无锁的多线程技术
//原子操作：多线程中不会被打断的代码执行片段
//区别：互斥量一般限制多条代码，原子操作一般限制单个变量
//
//原子操作，一般指“不可分割”的操作，也就是说操作状态只有完成和没完成，
//不可能出现半完成的状态
//atomic<>类模板
//atomic是一个结构体，用{}进行初始化最恰当
//使用：可以用来计数，不会出现误差
//
//






#include<iostream>
#include<future>
#include<list>
#include<string>
#include<mutex>
#include<thread>
#include<map>	

using namespace std;

// int mythread() {

// 	cout << "mythread() start	   " << "threadid" << this_thread::get_id() << endl;
// 	chrono::milliseconds dura(5000);
// 	this_thread::sleep_for(dura);
// 	cout << "mythread() end	   " << "threadid" << this_thread::get_id() << endl;
// 	//返回值
// 	return 5;
// }


// void mythread2(shared_future<int>& tmpf) {
// 	//get()多次没有问题
// 	auto result = tmpf.get();
// 	auto result = tmpf.get();
// 	auto result = tmpf.get();

// 	cout << "mythread2() start " << "threadid" << this_thread::get_id() << endl;
// 	cout << "mythread2 result is " << result << endl;
// 	return;
// }

//定义全局量，验证试想
//int g_mycount=0;
//定义原子量
//可以完全按照模板类型的使用方法使用
//例如下面的g_mycount可以完全按照int型来使用
//atomic<int> g_mycount=0;
atomic<int> g_mycount(0);
atomic<bool> g_ifend={false};

void mythread (){
	//定义1秒钟
	chrono::milliseconds dura(1000);
	while(g_ifend==false){
		cout<<"thread Id ="<<this_thread::get_id()<<"运行中"<<endl;
		this_thread::sleep_for(dura);
	}
	cout<<"thread Id ="<<this_thread::get_id()<<"结束"<<endl;

}




int main(int argc, char* argv[]) {
// 	cout << "main" << "threadID" << this_thread::get_id() << endl;
// 	future<int> result = async(launch::deferred,mythread);

// 	cout << "continue......!" << endl;
// 	int def = 0;
// 	cout << result.get() << endl;

// 	//枚举类型
// 	//等待1秒
// 	std::future_status status = result.wait_for(std::chrono::seconds(1));
// 	//如果等待超时
// 	if (status == std::future_status::timeout)
// 	{
// 		//表示程序还没有执行完成
// 		cout << "等待超时" << endl;
// 	}
// 	else if(status==future_status::ready){
// 		//表示线程返回
// 		cout << "成功返回" << endl;
// 		cout << result.get() << endl;
// 	}
// 	else if(status==future_status::deferred){
// 		//延迟，只有再async创建时候传入参数deferred时才会条件成立
// 		cout << "延迟条件成立" << endl;
// 		//只有get（）时，才会执行线程入口函数
// 		//而且使用get会使线程函数直接在主线程中调用，而不是创建新线程
// 		cout << result.get() << endl;
// 	}

	//验证试想
	//运行结果应该是两个线程的结果之和即g-mycount=200000
	//但是有时并不是这个结果（少于这个结果）
	//也就是在++的过程中可能被打断，结果无法正常完成++的操作
	// thread myobj(mythread);
	// thread myobj2(mythread);
	// myobj.join();
	// myobj2.join();
	// cout<<"两个进程执行完毕，g—mycount的结果是"<<g_mycount<<endl;


	//原子操作控制线程的执行
	//要求：等待五秒后线程执行
	thread myobj(mythread);
	chrono::milliseconds dura(50000);
	this_thread::sleep_for(drua);
	//设置开始执行
	g_ifend=true;
	myobj.join();



// 	cout << "I love china" << endl;
}